#include "list.h"

/*
Initializes a linked list
 */
void list_init(linklist *l, size_t e_size, KEYCMP k, DATACPY d, DELNODE n, PRINTNODE p) {
    l->THIS = l;
    l->_keycmpfn = k;
    l->_datacpyfn = d;
    l->_delnodefn = n;
    l->_printfn = p;

    l->e_size = e_size;
    l->head = NULL;
    l->tail = NULL;
}

/*
 Adds an element to the end of the list. O(1)
 */
void list_add(linklist *l, const void *n) {
    list_node *tmp ;

    /* Allocate a new node */
    tmp = (list_node *) malloc(sizeof (list_node));
    tmp->data = (char *) malloc(l->e_size);
    tmp->next = NULL;
    l->_datacpyfn(tmp->data, n);

    if (l->head == NULL)
        l->head = tmp;
    else l->tail->next = tmp;

    l->tail = tmp;
}

/*
 Traverses the list from first node to the last node.
 */
void list_traverse(const linklist *l) {
    list_node *tmp = l->head;

    while (tmp != NULL) {
        l->_printfn(tmp->data);
        tmp = tmp->next;
    }
}

/*
 Cleans the list.
 */
void list_clean(linklist *l) {
    list_node *tmp = l->head;

    while (tmp != NULL) {
        if (l->_delnodefn)
            l->_delnodefn(tmp->data);
        free(tmp->data);
        tmp = tmp->next;
    }

    l->head = l->tail = NULL;
    l->e_size = 0;
}